package org.chen.security.jwt;

import com.alibaba.nacos.common.utils.StringUtils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

@Component
@Data
@Slf4j
public class JwtUtils {
    @Value("${jwt.secret}")
    private String secret;
    
    @Value("${jwt.expiration}")
    private Long expiration;

    private static final String TOKEN_PREFIX = "Bearer ";
    private static final String HEADER_STRING = "Authorization";
    
    /**
     * 生成token
     */
    public String generateToken(String username) {
        Algorithm algorithm = Algorithm.HMAC512(secret);  // 使用 HMAC512 加密算法
        return JWT.create()
                .withSubject(username)                     // 设置 JWT 主题（用户）
                .withClaim("username", username)            // 添加自定义的 claim
                .withIssuedAt(new Date())                   // 设置签发时间
                .withExpiresAt(new Date(System.currentTimeMillis() + expiration))  // 设置过期时间
                .sign(algorithm);                           // 使用 HMAC512 加密算法签名
    }
    
    /**
     * 从token中获取用户名
     */
    public String getUsernameFromToken(String token) {
        DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC512(secret))  // 使用与签名时相同的密钥
                .build()
                .verify(token);// 验证并解析 token
        return decodedJWT.getSubject();  // 返回解析后的用户名（subject）
    }
    
    /**
     * 验证token
     */
    public boolean validateToken(String token) {
        try {
            JWT.require(Algorithm.HMAC512(secret))  // 使用 HMAC512 加密算法验证密钥
                    .build()
                    .verify(token);                      // 如果验证失败，会抛出异常
            return true;  // 验证通过
        } catch (JWTVerificationException e) {
            log.error("Invalid JWT token: {}", e.getMessage());  // 处理验证失败的异常
        }
        return false;
    }

    /**
     * 从请求中获取token
     */
    public String getTokenFromRequest(HttpServletRequest request) {
        String bearerToken = request.getHeader(HEADER_STRING);
        if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(TOKEN_PREFIX)) {
            return bearerToken.substring(TOKEN_PREFIX.length());
        }
        return null;
    }
}